﻿using Autofac.Extensions.DependencyInjection;
using EntityFrameWorkCore;
using FrameWorkCore.CustomFilter.Dto;
using FrameWorkCore.EFCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrameWorkCore.CustomFilter
{
    
    public class CustomExceptionFilter : ExceptionFilterAttribute
    {
        private readonly IEnumerable<AbstractShardingDbContext> dbContexts;
        private readonly IServiceProvider serviceProvider;
        public CustomExceptionFilter(IServiceProvider _serviceProvider)
        {
            serviceProvider = _serviceProvider;
            dbContexts = ((AutofacServiceProvider)_serviceProvider).LifetimeScope.ComponentRegistry.Registrations
            .Where(x => typeof(AbstractShardingDbContext).IsAssignableFrom(x.Activator.LimitType))
            .Select(x => (AbstractShardingDbContext)serviceProvider.GetService(x.Activator.LimitType));
        }



        public override async Task OnExceptionAsync(ExceptionContext context)
        {
            var currDbContexts = dbContexts.Where(x => x.Database.CurrentTransaction != null);
            foreach (var dbContext in currDbContexts)
               await dbContext.Database.RollbackTransactionAsync();

            context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.ExceptionHandled = true;

            var resultDto = new ResultDto();
                resultDto.Code = StatusCodes.Status500InternalServerError;

            if (context.Exception is IUserFriendlyException)
                resultDto.Msg = context.Exception.Message;
            else if (context.Exception is DbUpdateConcurrencyException)
                resultDto.Msg = "The data has been amended by others, modify the failure!";
            else
                resultDto.Msg = "I'm sorry, happened during processing requests a server internal abnormal!";

            context.Result = new JsonResult(resultDto);

        }
            
            
    }
}
